<?php

require_once 'Gepard/classes/dbo/Interface.php';
require_once 'Gepard/classes/dbo/Abstract.php';
require_once 'Gepard/classes/dbo/Query.php';
require_once 'Gepard/classes/dbo/Table.php';
/**
 * 
 * Enter description here ...
 * @author taras
 *
 */
class gDbo extends gCoreObject
{	
	/**
	 * 
	 * Enter description here ...
	 * @var gDboQuery
	 * @see gDboQuery
	 */
	public $query = null;
	/**
	 * 
	 * Enter description here ...
	 * @var gDboTable
	 */
	public $table = null;
	/**
	 * 
	 * Enter description here ...
	 * @var gDboAdapterAbstract
	 */
	private $_adapter = null;
	/**
	 * 
	 * Enter description here ...
	 * @var array
	 */	
	private $_adapters = array();
	
	private $_connectedDrivers = array();
		
	public function init()
	{
		$this->query = new gDboQuery($this);
		
		$this->table = new gDboTable($this);
	}
	
	public function probeconnection()
	{
		
	}
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $options
	 */
	public function connect($options=null)
	{
		$options = $options==null ? gApp::get('dboconf') : $options;
		
		if (is_array($options) )
		{
			foreach ($options as $adapter=>$options)
			{
				$parts = explode(':', $adapter);
				
				$subcount = null;
				
				if (count($parts) > 1)
				{
					$adapter = $parts[0];
					$subcount = ':' . $parts[1];
				}
				$name = $adapter . $subcount;
				
				$this->preloadAdapter($adapter,$subcount);
				
				$this->_adapters[$name]->connect($options);
				
				$this->_adapter = $this->_adapters[$name];
				
				$this->_connectedDrivers[$adapter] = $this->_adapter;
			}
		}
		else
		{
			throw new gException('There were no db adapters to connect', gError::INTERNAL);
		}
	}
	/**
	 * (non-PHPdoc)
	 * @see gKernel::getAdapter()
	 */	
	public function getAdapter($name)
	{
		if( array_key_exists($name, $this->_adapters))
		{
			return $this->_adapters[$name];
		}
		throw new gException('Adapter "'.$name.'" was not connected');
	}
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $name
	 * @param unknown_type $subcount
	 * @throws Exception
	 */
	public function preloadAdapter($name,$subcount=null)
	{
		$adapter   = $name . $subcount;
		
		if( array_key_exists($adapter, $this->_adapters))
		{
			throw new gException('Adapter "'.$adapter.'" has been already connected');	
		}
		
		$classname = 'gDbo'.ucfirst($name);
				
		if ( array_key_exists($name,$this->_connectedDrivers))
		{
			$adapterobj = clone $this->_connectedDrivers[$name];
		}
		else
		{
			gCore::includeAdapterFile('dbo', $name);
			
			$adapterobj = new $classname ($this->core);
		}
		$adapterobj->init();
		
		$this->_adapters[$adapter] = $adapterobj;
	}
	
	/**
	 * 
	 * @return gDboQuery
	 */
	public function select()
	{
		return $this->query->select();
	}
	/**
	 * 
	 * @return gDboQuery
	 */
	public function update()
	{
		return $this->query->update();
	}
	/**
	 * 
	 * @return gDboQuery
	 */
	public function delete()
	{
		return $this->query->delete();
	}
	public function insert()
	{
		
	}
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $sql
	 * @param unknown_type $data
	 */
	public function prepare($sql)
	{
		return call_user_func_array(array($this->_adapter,'prepare'), func_get_args());
	}
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $sql
	 * @param unknown_type $result
	 */	
	public function execute($sql,$result=null)
	{
		if( is_object($sql) )
		{
			$sql = $sql->toString();
		}
		return $this->_adapter->execute($sql,$result);
	}
	/**
	 * 
	 * Enter description here ...
	 */
	public function disconnect()
	{
		foreach ( $this->_adapters as $name => $object )
		{
			$object->disconnect();
		}
	}
}